package rabbitmq.test;

import com.rabbitmq.client.*;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * rabbitmq组件 exchange交换机 有默认的7个 queue默认空的
 * 所以如果希望使用这个中间件,第一件事就是使用开发语言客户端代码
 * 连接rabbitmq实现组件声明(创建)
 */
public class Declare {
    //每一个测试类都准备一个连接对象
    private Channel channel;

    @Before
    public void init() {
        //1.创建长连接 提供属性(ip,port,username,password,virtualHost)
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.8.100");
        factory.setPort(5672);//TCP协议端口
        factory.setUsername("admin");
        factory.setPassword("123456");
        factory.setVirtualHost("/");
        try {
            Connection connection = factory.newConnection();
            //2.从长连接赋值短链接
            channel = connection.createChannel();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("创建连接失败");
        }
    }

    @Test
    public void queueDeclare() throws IOException {
        //声明组件包括 交换机和队列
        /**
         * 参数详解
         * String queue: 创建的队列名称,在虚拟主机中 只能存在唯一名称
         * Boolean durable: 队列是否持久化 true在rabbitmq重启之后 队列保持存在 false不存在
         * Boolean exclusive: 队列是绑定当前连接对象(独占 专属) true别的链接无法操作队列 false所有连接都可以操作队列
         * Boolean autoDelete: 队列是否自动删除 true队列从第一个监听消费者开始计算,到最后一个消费者断开连接,自动删除 false不删除
         * Map<String,Object> args: 队列特性参数,key值是rabbitmq固定的,比如
         * "x-expires" 1000S 队列过期时间 当队列没有产生消息,没有消费监听 最长等待时间1000s
         */
        channel.queueDeclare("queue01", true, false, false, null);
    }

    // 声明一个交换机和两个队列，已经确认绑定关系
    // 路由交换机
    @Test
    public void declareEXQueue() throws IOException {
        channel.queueDeclare("ex_queue01", true, false, false, null);
        channel.queueDeclare("ex_queue02", true, false, false, null);

        /**
         * 参数详解
         * String exchange: 交换机名称
         * String type: 交换机类型 direct fanout topic headers
         * Boolean durable: 交换机是否持久化 true在rabbitmq重启之后 队列保持存在 false不存在
         * Boolean autoDelete: 交换机是否自动删除 true交换机从第一个监听消费者开始计算,到最后一个消费者断开连接,自动删除 false不删除
         * Map<String, Object> args: 交换机的其他特性参数,key值是rabbitmq固定的,比如直接还是间接交换机
         */
        channel.exchangeDeclare("direct_ex", "direct", true, false, null);
        // 自定义队列和交换机的绑定关系（北京、上海）
        channel.queueBind("ex_queue01", "direct_ex", "北京");
        channel.queueBind("ex_queue02", "direct_ex", "上海");
        // 同一个队列和交换机可以存在多个绑定关系
        channel.queueBind("ex_queue01", "direct_ex", "哈尔滨");
    }

    // 发布订阅交换机
    @Test
    public void declareFanout() throws IOException {
        channel.queueDeclare("ex_queue03", true, false, false, null);
        channel.queueDeclare("ex_queue04", true, false, false, null);
        //声明交换机
        /**
         * String exchange: 交换机名称
         * String type: 交换机类型 direct fanout topic headers
         * Boolean durable: 交换机是否持久化 如果true 关闭rabbitmq 重启 交换机依然存在
         * Boolean autoDelete: 交换机是否自动删除 如果true 有至少一个交换机或者队列绑定这个交换机之后,直到所有的绑定都解除,自动删除
         * Map<String,Object> arguments: 其他属性,比如是否是直接还是间接交换机
         */
        channel.exchangeDeclare("fanout_ex", "fanout", true, false, null);
        //自定义队列和交换机的绑定关系 北京 上海
        channel.queueBind("ex_queue03", "fanout_ex", "北京");
        //同一个队列和交换机可以存在多个绑定关系
        channel.queueBind("ex_queue04", "fanout_ex", "哈尔滨");
    }

    // 主题交换机
    @Test
    public void declareTopic() throws IOException {
        channel.queueDeclare("ex_queue05", true, false, false, null);
        channel.queueDeclare("ex_queue06", true, false, false, null);
        //声明交换机
        /**
         * String exchange: 交换机名称
         * String type: 交换机类型 direct fanout topic headers
         * Boolean durable: 交换机是否持久化 如果true 关闭rabbitmq 重启 交换机依然存在
         * Boolean autoDelete: 交换机是否自动删除 如果true 有至少一个交换机或者队列绑定这个交换机之后,直到所有的绑定都解除,自动删除
         * Map<String,Object> arguments: 其他属性,比如是否是直接还是间接交换机
         */
        channel.exchangeDeclare("topic_ex", "topic", true, false, null);
        //自定义队列和交换机的绑定关系 北京 上海
        channel.queueBind("ex_queue05", "topic_ex", "北京");
        //同一个队列和交换机可以存在多个绑定关系
        channel.queueBind("ex_queue06", "topic_ex", "中国.#");
    }

    // 混合多交换机
    @Test
    public void declareMix() throws IOException {
        channel.queueDeclare("ex_queue07", true, false, false, null);
        channel.queueDeclare("ex_queue08", true, false, false, null);
        //声明交换机
        /**
         * String exchange: 交换机名称
         * String type: 交换机类型 direct fanout topic headers
         * Boolean durable: 交换机是否持久化 如果true 关闭rabbitmq 重启 交换机依然存在
         * Boolean autoDelete: 交换机是否自动删除 如果true 有至少一个交换机或者队列绑定这个交换机之后,直到所有的绑定都解除,自动删除
         * Map<String,Object> arguments: 其他属性,比如是否是直接还是间接交换机
         */
        channel.exchangeDeclare("direct_ex2", "direct", true, false, null);
        channel.exchangeDeclare("fanout_ex2", "fanout", true, false, null);
        //自定义队列和交换机的绑定关系 北京 上海
        channel.queueBind("ex_queue07", "direct_ex2", "重庆");
        //同一个队列和交换机可以存在多个绑定关系
        channel.queueBind("ex_queue08", "fanout_ex2", "中国.#");
    }

    // 根据属性自定义队列过期时间
    @Test
    public void queueExpireDeclare() throws IOException {
        Map<String,Object> args=new HashMap<>();
        //x-expire 20000
        args.put("x-expires",20000);
        channel.queueDeclare("queue01", false, false, false, args);
    }
}